using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Channels;
using System.Data;
using Shared;
using System.Diagnostics;

namespace Client
{
    public class Program
    {
        public static void Main(string[] args)
        {
            System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(1033);
            System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(1033);

            Console.WriteLine("Press any key when the service is available.");
            Console.ReadKey();

            factory = new ChannelFactory<IDSService>("DSService");

            int times = 100;

            Console.WriteLine("============= Exclude Schema; Binary Serialization (Ignore the results below; the test will be repeated)");
            CompareSendingDataSet(times, 1, false, true);
            CompareSendingDataSet(times, 100, false, true);
            CompareSendingDataSet(times, 200, false, true);

            Console.WriteLine("============= Exclude Schema; Binary Serialization");
            CompareSendingDataSet(times, 1, false, true);
            CompareSendingDataSet(times, 100, false, true);
            CompareSendingDataSet(times, 200, false, true);

            Console.WriteLine("============= Exclude Schema; Xml Serialization");
            CompareSendingDataSet(times, 1, false, false);
            CompareSendingDataSet(times, 100, false, false);
            CompareSendingDataSet(times, 200, false, false);

            Console.WriteLine("============= Include Schema; Binary Serialization");
            CompareSendingDataSet(times, 1, true, true);
            CompareSendingDataSet(times, 100, true, true);
            CompareSendingDataSet(times, 200, true, true);

            Console.WriteLine("============= Include Schema; Xml Serialization");
            CompareSendingDataSet(times, 1, true, false);
            CompareSendingDataSet(times, 100, true, false);
            CompareSendingDataSet(times, 200, true, false);

            Console.WriteLine("================================================");
            Console.WriteLine("============= Plain Human object");
            CompareSendingPlainObject(times);

            Console.ReadKey();
        }

        private static void CompareSendingDataSet(int times, int dsSize, bool includeSchema, bool binarySerialization)
        {
            decimal sum;

            sum = InvokeService(true, true, times, dsSize, includeSchema, binarySerialization);
            Console.WriteLine("WCF[{1}]: {0}", sum / times, dsSize);

            sum = InvokeService(false, true, times, dsSize, includeSchema, binarySerialization);
            Console.WriteLine("Remoting[{1}]: {0}", sum / times, dsSize);
            
            Console.WriteLine();
        }

        private static void CompareSendingPlainObject(int times)
        {
            decimal sum;

            sum = InvokeService(true, false, times, 0, false, false);
            Console.WriteLine("WCF: {0}", sum / times);

            sum = InvokeService(false, false, times, 0, false, false);
            Console.WriteLine("Remoting: {0}", sum / times);

            Console.WriteLine();
        }

        private static decimal InvokeService(bool wcf, bool testDataSet, int times, int dsSize, bool includeSchema, bool binarySerialization)
        {
            Stopwatch s = new Stopwatch();
            s.Start();

            for (int i = 0; i < times; i++)
            {
                InvokeServiceMethod(wcf, testDataSet, dsSize, includeSchema, binarySerialization);
            }
            
            s.Stop();

            return s.ElapsedMilliseconds;
        }

        private static ChannelFactory<IDSService> factory;

        private static void InvokeServiceMethod(bool wcf, bool testDataSet, int dsSize, bool includeSchema, bool binarySerialization)
        {
            IDSService proxy = null;
            if (wcf)
                proxy = factory.CreateChannel();
            else
                proxy = (IDSService)Activator.GetObject(typeof(IDSService), "tcp://localhost:63099/DSServiceRemoting.rem");

            if (testDataSet)
                proxy.LoadDataSet(dsSize, includeSchema, binarySerialization);
            else
                proxy.LoadPlainObject();

            if (wcf)
                ((IChannel)proxy).Close();
        }
    }
}
